home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / CODECS.ZIP / codecs / english / codrle2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-13  |  6.7 KB  |  183 lines

  1. /* File: codrle2.c
  2.    Author: David Bourgin
  3.    Creation date: 1/2/94
  4.    Last update: 24/7/95
  5.    Purpose: Example of RLE type 2 encoding with a file source to compress.
  6. */
  7.  
  8. #include <stdio.h>
  9. /* For routines printf,fgetc,fputc and rewind */
  10. #include <memory.h>
  11. /* For routine memset */
  12. #include <stdlib.h>
  13. /* For routine exit */
  14.  
  15. /* Error codes sent to the caller */
  16. #define NO_ERROR      0
  17. #define BAD_FILE_NAME 1
  18. #define BAD_ARGUMENT  2
  19.  
  20. /* Useful constants */
  21. #define FALSE 0
  22. #define TRUE  1
  23.  
  24. /* Global variables */
  25. FILE *source_file,*dest_file;
  26.  
  27.                              /* Being that fgetc=EOF only after an access
  28.                                 then 'byte_stored_status' is 'TRUE' if a byte has been stored by 'fgetc'
  29.                                 or 'FALSE' if there's no valid byte not already read and not handled in 'val_byte_stored' */
  30. int byte_stored_status=FALSE;
  31. int val_byte_stored;
  32.  
  33. /* Pseudo procedures */
  34. #define beginning_of_data()  (byte_stored_status=FALSE,(void)rewind(source_file))
  35. #define end_of_data()  (byte_stored_status?FALSE:!(byte_stored_status=((val_byte_stored=fgetc(source_file))!=EOF)))
  36. #define read_byte()  (byte_stored_status?byte_stored_status=FALSE,(unsigned char)val_byte_stored:(unsigned char)fgetc(source_file))
  37. #define write_byte(byte)  ((void)fputc((byte),dest_file))
  38.  
  39. void rle2write_rep(header_byte,repeated_byte,repetition_number)
  40. /* Returned parameters: None
  41.    Action: Writes in the output compression stream the encoding of 'repetition_number' times 'repeated_byte'.
  42.    'header_byte' is used as marker as defined in RLE 2 method
  43.    Errors: An input/output error could disturb the running of the program
  44. */
  45. unsigned char header_byte,repeated_byte;
  46. unsigned int repetition_number;
  47. { if (repetition_number<4)
  48.      if (repeated_byte==header_byte)
  49.         { write_byte(header_byte);
  50.           write_byte(repetition_number-1);
  51.         }
  52.      else { register unsigned int i;
  53.  
  54.             for (i=1;i<=repetition_number;i++)
  55.                 write_byte(repeated_byte);
  56.           }
  57.   else { write_byte(header_byte);
  58.          write_byte(repetition_number-1);
  59.          write_byte(repeated_byte);
  60.        }
  61. }
  62.  
  63. void rle2write_non_rep(header_byte,non_repeated_byte)
  64. /* Returned parameters: None
  65.    Action: Writes in the output compression stream the encoding of 'non_repeated_byte'
  66.    'header_byte' is used as marker as defined in RLE 2 method
  67.    Errors: An input/output error could disturb the running of the program
  68. */
  69. unsigned char header_byte,non_repeated_byte;
  70. { if (non_repeated_byte==header_byte)
  71.      { write_byte(header_byte);
  72.        write_byte(0);
  73.      }
  74.   else write_byte(non_repeated_byte);
  75. }
  76.  
  77. void rle2encoding()
  78. /* Returned parameters: None
  79.    Action: Compresses with RLE type 2 method all bytes read by the function read_byte
  80.    Errors: An input/output error could disturb the running of the program
  81. */
  82. { unsigned char byte1,byte2,header_byte;
  83.   unsigned int frame_size;
  84.   register unsigned int i;
  85.   unsigned long int lookup_table[256];
  86.  
  87.   if (!end_of_data())        /* Is there at least a byte to analyze? */
  88.      {                       /* Sets up the occurrence numbers of all bytes to 0 */
  89.        (void)memset((char *)lookup_table,0,sizeof(lookup_table));
  90.                              /* This is the same to fill 'lookup_table' to 0.
  91.                                 It's fastest than to loop 256 times */
  92.        while (!end_of_data())/* Valids the occurrences in 'lookup_table' in regard to the data to compress */
  93.              { byte1=read_byte();
  94.                lookup_table[byte1]++;
  95.              }
  96.        header_byte=0;
  97.        for (i=1;i<=255;i++)
  98.            if (lookup_table[i]<lookup_table[header_byte])
  99.               header_byte=i;
  100.        write_byte(header_byte);
  101.        beginning_of_data();  /* New data analysis */
  102.        byte1=read_byte();
  103.        frame_size=1;
  104.        if (!end_of_data())
  105.                              /* Are there at least two bytes? */
  106.           { byte2=read_byte();
  107.             frame_size=2;
  108.             do {             /* Real beginning of the compression */
  109.                  if (byte1==byte2)
  110.                              /* Do we meet only a sequence of identical bytes? */
  111.                     { while ((!end_of_data())&&(byte1==byte2)&&(frame_size<256))
  112.                             { byte2=read_byte();
  113.                               frame_size++;
  114.                             }
  115.                       if (byte1==byte2)
  116.                          { rle2write_rep(header_byte,byte1,frame_size);
  117.                            if (!end_of_data())
  118.                               { byte1=read_byte();
  119.                                 frame_size=1;
  120.                               }
  121.                            else frame_size=0;
  122.                          }
  123.                       else { rle2write_rep(header_byte,byte1,frame_size-1);
  124.                              byte1=byte2;
  125.                              frame_size=1;
  126.                            }
  127.                     }
  128.                  else {      /* No, then don't handle the last byte */
  129.                         rle2write_non_rep(header_byte,byte1);
  130.                         byte1=byte2;
  131.                         frame_size=1;
  132.                       }
  133.                  if (!end_of_data())
  134.                     { byte2=read_byte();
  135.                       frame_size=2;
  136.                     }
  137.                }
  138.             while ((!end_of_data())||(frame_size>=2));
  139.           }
  140.        if (frame_size==1)  /* Was there a last byte to analyze? */
  141.           rle2write_non_rep(header_byte,byte1);
  142.      }
  143. }
  144.  
  145. void help()
  146. /* Returned parameters: None
  147.    Action: Displays the help of the program and then stops its running
  148.    Errors: None
  149. */
  150. { printf("This utility enables you to compress a file by using RLE type 2 method\n");
  151.   printf("as given in 'La Video et Les Imprimantes sur PC'\n");
  152.   printf("\nUse: codrle2 source target\n");
  153.   printf("source: Name of the file to compress\n");
  154.   printf("target: Name of the compressed file\n");
  155. }
  156.  
  157. int main(argc,argv)
  158. /* Returned parameters: Returns an error code (0=None)
  159.    Action: Main procedure
  160.    Errors: Detected, handled and an error code is returned, if any
  161. */
  162. int argc;
  163. char *argv[];
  164. { if (argc!=3)
  165.      { help();
  166.        exit(BAD_ARGUMENT);
  167.      }
  168.   else if ((source_file=fopen(argv[1],"rb"))==NULL)
  169.           { help();
  170.             exit(BAD_FILE_NAME);
  171.           }
  172.        else if ((dest_file=fopen(argv[2],"wb"))==NULL)
  173.                { help();
  174.                  exit(BAD_FILE_NAME);
  175.                }
  176.             else { rle2encoding();
  177.                    fclose(source_file);
  178.                    fclose(dest_file);
  179.                  }
  180.   printf("Execution of codrle2 completed.\n");
  181.   return (NO_ERROR);
  182. }
  183.